#ifndef _TD_H_
#define _TD_H_

#include <pq.h>
#include <defs.h>
#include <request.h>

#define MSG_BUFFER_SIZE 256

typedef struct __td {
  int id;               		// internal id of this task
  int sp;               		// stack pointer
  int spsr;             		// status register
  int ret;              		// space for return values from system calls
  int mode;                 // is this a software or hardware interrupt?
  // NOTE: everything above this line is position-dependent. DO NOT CHANGE
  // THE ORDER OF THESE FIELDS UPON PAIN OF HORRIBLE FIERY DEATH.
  /* ==================================================================== */
  struct __td *parent;  		// pointer to parent task (NULL for first task)
  int pri;              		// priority of this task
  int state;            		// state (e.g. ready, active, etc.)
  // priority queue links
  struct __td *next;    		// pointer to next task in priority queue
  struct __td *prev;    		// pointer to previous task in priority queue
  // Send/Receive/Reply queues
  pq sendQ;									// the send queue of the Send/Receive/Reply IPC
  // extra state for Send/Receive/Reply
  char *msg;								// pointer to a message buffer to be processed
  int msg_len;							// the length of the message buffer
  char *reply;							// pointer to a reply buffer to be returned
  int reply_len;						// the length of the reply buffer
  int *sender_tid;					// the sender's task ID used by the receiver
  // extra state for AwaitEvent
  char *event;              // buffer for volatile event data
  int event_len;            // the length of the event buffer
  char name[MAX_NAME_LEN];  // the name of the task for debugging purposes
  req request;              // the last system call's request data (debugging)
  int tag;                  // debugging flag
} td;

/* Pushes the value onto the user stack */
void TdPushRegister( td *task, int reg );

#endif
